﻿using ControllerManageServer.PacketParsing;
using Controller.Enum;
using Controller.Model;
using Leeder.Communi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Leeder.Interface.Communi;

namespace ControllerManageServer.Handler
{
    /// <summary>
    /// DPS通信Socket
    /// </summary>
    internal class DpsSocketServerHandler : ServerSocketHandler
    {
        #region 变量声明

        /// <summary>
        /// 心跳
        /// </summary>
        private const UInt16 HEART_BEAT = 1;

        #endregion 变量声明


        #region 定义事件

        /// <summary>
        /// 数据接收,string=ip:port,byte[]接收到的数据
        /// </summary>
        public event Action<string, byte[]> OnDataReceive;
        /// <summary>
        /// socket取对应ip端口发送数据的委托
        /// </summary>
        /// <param name="key">ip:port</param>
        /// <returns></returns>
        public delegate byte[] GetSendDataDelegate(string key);
        /// <summary>
        /// 实现socket取对应ip端口发送数据
        /// </summary>
        /// <param name="key">ip:port</param>
        /// <returns></returns>
        public event GetSendDataDelegate GetSendDataEvent;

        #endregion 定义事件

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public DpsSocketServerHandler(string ip, int port) : base(ip, port, ProtocolType.Tcp)
        {

        }

        /// <summary>
        /// 获取报文解析对象
        /// </summary>
        /// <returns></returns>
        protected override IPacketParsing GetPacketParsing()
        {
            return new DpsPacketParsing();
        }

        /// <summary>
        /// 报文处理
        /// </summary>
        /// <param name="iPacket">报文解析对象</param>
        /// <param name="parsingPackets">解析后的报文列表</param>
        protected override void PacketHandle(IPacketParsing iPacket, List<byte[]> parsingPackets)
        {
            string key = iPacket.SocketObj.RemoteEndPoint.ToString();
            byte[] data = null;
            parsingPackets.ForEach(p =>
            {
                data = GetSendDataEvent?.Invoke(key);
                // 如果没有发送数据
                if (data == null || data.Length == 0)
                {
                    data = GetHeartbeat();
                }
                SendData(iPacket.SocketObj, data);
                data = null;
                OnDataReceive?.Invoke(key, p);
            });
        }

        /// <summary>
        /// 获取心跳包
        /// </summary>
        /// <returns></returns>
        private byte[] GetHeartbeat()
        {
            //List<byte> result = new List<byte>();

            //result.Add(0x8D);
            //result.AddRange(BitConverter.GetBytes(HEART_BEAT));
            //result.AddRange(BitConverter.GetBytes((UInt16)0));
            //result.Add(0x8F);
            //return result.ToArray();

            ServerPacketModel model = new ServerPacketModel { CmdType = CommunicationCmdTypeEnum.HEART_BEAT, BodyLength = 0 };
            return model.Serialize();
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="iDatas">数据报文字节数组</param>
        /// <param name="iStartPosition">起始位置</param>
        /// <param name="iLength">长度</param>
        private void SendData(Socket iSocket, byte[] iDatas, int iStartPosition, int iLength)
        {
            try
            {
                int position = iStartPosition, endPosition = iLength + iStartPosition;
                while (position < endPosition)
                {
                    position += iSocket.Send(iDatas, position, endPosition - position, SocketFlags.None);
                }
            }
            catch
            {
                //SocketConnectionEvent(iSocket, false);
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="iDatas"></param>
        private void SendData(Socket iSocket, byte[] iDatas)
        {
            SendData(iSocket, iDatas, 0, iDatas.Length);
        }
    }
}
